from PyQt5.QtCore import Qt, QThread, pyqtSignal, QTimer
from auto_import_file import handle_file_dialog_by_handle
from ws import send_and_wait_response
from config import load_config
from unzip import get_all_files,extract_filename_from_path
import pyautogui
import win32gui
import win32con
import win32api
import glom
import time
import json
import os

class ExecuteFlowThread(QThread):
    message_signal = pyqtSignal(str)
    log_signal = pyqtSignal(str)

    def __init__(self, extend, file_path, extensions, tasks, source):
        super().__init__()
        self.config, errorMsg = load_config()
        if errorMsg:
            self.log_signal.emit(errorMsg)
        self.file_path = file_path
        self.extend = extend
        self.extensions = extensions
        self.tasks = tasks
        self.source = source
        self.running_task = False

    def stop(self):
        self.running_task = False

    def run(self):
        try:
            self.log_signal.emit("开始执行流程...")
            if self.config.get("auto_open", False):
                url = self.config.get("web_link", "")
                if url:
                    self.open_webpage(url)
                else:
                    self.log_signal.emit(f"❌ 未配置平台地址 {url}")
            else:
                self.log_signal.emit("❌ 未开启自动化")
            self.log_signal.emit("✅ 执行完成！")
        except Exception as e:
            self.log_signal.emit(f"❌ 执行出错：{e}")

    def is_browser_open(self):
        import psutil
        browsers = ["chrome", "360", "360se", "360chrome"]
        for proc in psutil.process_iter(attrs=["name"]):
            name = proc.info["name"].lower()
            if any(b in name for b in browsers):
                return True
        return False
    
    
    def find_chrome_windows(self):
        """
        查找所有标题以'Google Chrome'结尾的窗口
        """
        chrome_windows = []
        
        def enum_windows_proc(hwnd, lParam):
            if win32gui.IsWindowVisible(hwnd):
                title = win32gui.GetWindowText(hwnd)
                # if title and ("360" in title or "chrome" in title.lower()):
                if title and ("360" in title):
                    chrome_windows.append((hwnd, title))
            return True
        
        win32gui.EnumWindows(enum_windows_proc, None)
        return chrome_windows

    def maximize_chrome_window(self,hwnd, title):
        """
        最大化指定的Chrome窗口
        """
        if not win32gui.IsWindow(hwnd):
            print(f"窗口句柄无效: {title}")
            return False
        
        try:
            # 先恢复窗口显示（如果最小化）
            win32gui.ShowWindow(hwnd, win32con.SW_RESTORE)
            
            # 设置窗口最大化
            win32gui.ShowWindow(hwnd, win32con.SW_MAXIMIZE)
            
            # 使用键盘事件辅助激活窗口
            win32api.keybd_event(0x12, 0, 0, 0)  # Alt键
            win32api.keybd_event(0x12, 0, win32con.KEYEVENTF_KEYUP, 0)
            
            # 设置窗口前置
            win32gui.SetForegroundWindow(hwnd)
            
            print(f"✅ 成功最大化并前置: {title}")
            return True
            
        except Exception as e:
            print(f"❌ 设置窗口失败: {e}")
            return False

    def maximize_all_chrome_windows(self):
        """
        最大化所有以'Google Chrome'结尾的窗口
        """
        print("🔍 正在查找Google Chrome窗口...")
        chrome_windows = self.find_chrome_windows()
        
        if not chrome_windows:
            print("❌ 未找到标题以'Google Chrome'结尾的窗口")
            print("提示: 请确保Chrome浏览器正在运行，且窗口标题包含'Google Chrome'")
            return
        
        print(f"📋 找到 {len(chrome_windows)} 个Chrome窗口:")
        for i, (hwnd, title) in enumerate(chrome_windows):
            print(f"  {i+1}. {title}")
        
        success_count = 0
        for hwnd, title in chrome_windows:
            if self.maximize_chrome_window(hwnd, title):
                success_count += 1
                time.sleep(0.5)  # 短暂延迟避免冲突
        
        print(f"\n📊 操作完成: 成功最大化 {success_count}/{len(chrome_windows)} 个Chrome窗口")

    def excute_task(self):
        if self.extend:
            type = self.extend.get("type")
            if type == "yx":
                
                if self.extensions == "zip" or self.extensions == "rar" or self.extensions == "7z":
                    self.running_task = True
                    for task in self.tasks:
                        if not self.running_task:
                            self.log_signal.emit(f"外部原因，终止流程 当前执行到:{task.get('dsc')}")
                            break
                        
                        # 检查是否是获取坐标点
                        if task.get("type") == "point":
                            jsonPath = task.get("jsonPath")
                            source = json.loads(self.source)
                            attachmentPaths = None
                            try:
                                attachmentPaths = glom(source, jsonPath)
                            except:
                                pass
                            if attachmentPaths and len(attachmentPaths) >0:
                                if self.extensions == "zip" and str(self.file_path).endswith("_extracted"):
                                    files = get_all_files(self.file_path)
                                    filters = [file for file in files if extract_filename_from_path(file) in attachmentPaths]
                            for file in filters:
                                if resp:
                                    self.log_signal.emit(f"浏览器返回：{resp}")
                                    if resp and "," in resp:
                                        points = resp.split(",")
                                        pyautogui.moveTo(int(points[0]), int(points[1]), duration=0.5)
                                        pyautogui.click()
                                        self.log_signal.emit(f"找到坐标： {points[0]},{points[1]}")
                                        time.sleep(1)  
                                        self.log_signal.emit(f"准备上传附件 {file}")
                                        handle_file_dialog_by_handle(file)
                                        ack_field_text = send_and_wait_response(json.dumps(task.get("remark")), timeout=2)
                                        print(f"ack_field_text: {ack_field_text}")
                                        if extract_filename_from_path(file) in ack_field_text:
                                            print(f"附件上传成功{file}")
                                            self.log_signal.emit(f"附件上传成功 {file}")
                                        else:
                                            print(f"附件上传失败{file}")
                                            self.log_signal.emit(f"附件上传失败 {file}")
                                    else:
                                        self.log_signal.emit(f"未找到坐标： {resp}")
                                else:
                                    self.log_signal.emit("等待浏览器响应超时。")
                        else:
                            resp = send_and_wait_response(json.dumps(task), timeout=2)
                            if resp:
                                self.log_signal.emit(f"浏览器返回：{resp}")
                            else:
                                self.log_signal.emit("等待浏览器响应超时。")
                        self.log_signal.emit(f"浏览器返回：{resp}")
                else:
                    yx_flow = self.config.get("yx_flow", [])
                    if yx_flow and len(yx_flow) > 0:
                        self.running_task = True
                        for flow in yx_flow:
                            
                            if not self.running_task:
                                self.log_signal.emit(f"外部原因，终止流程 当前执行到:{flow.get('dsc')}")
                                break
                                
                            self.log_signal.emit(f"执行流程:{flow.get('dsc')}")
                            
                            if flow.get("type") == "file":
                                try:
                                    # 查找屏幕上的图像位置
                                    xpath = flow.get("xpath", "xpath.png")
                                    xpaths = xpath.split(",")
                                    img_clieked = False
                                    for path in xpaths:
                                        retry_count = 0
                                        real_path = os.path.join(os.getcwd(), path)
                                        print(f"{real_path}")
                                        while retry_count < 3:
                                            if real_path != "" and os.path.exists(real_path):
                                                try:
                                                    button_location = pyautogui.locateOnScreen(real_path, confidence=0.7)
                                                    # 如果找到了该图像
                                                    if button_location:
                                                        # 获取图像中心的坐标
                                                        center = pyautogui.center(button_location)
                                                        # 点击该位置
                                                        pyautogui.click(center)
                                                        print(f"点击了 {center} 位置")
                                                        self.log_signal.emit(f"点击了 {center} 位置")
                                                        time.sleep(1)
                                                        handle_file_dialog_by_handle(self.file_path)
                                                        img_clieked = True
                                                        break
                                                    else:
                                                        print("未找到指定图像！")
                                                        self.log_signal.emit("未找到指定图像！")
                                                        retry_count += 1
                                                except Exception as e:
                                                    retry_count += 1
                                                    self.log_signal.emit(f"没匹配到图像{e}")
                                                    print(f"没匹配到图像{e}")
                                                time.sleep(1)  
                                            else:
                                                print(f"${real_path}路径不存在")
                                                self.log_signal.emit(f"${real_path}路径不存在")
                                                handle_file_dialog_by_handle(self.file_path)
                                                break
                                        if img_clieked:
                                            break
                                        
                                        
                                except Exception as e:
                                    print(f"未找到指定图像 ERR！{e}")
                                    self.log_signal.emit(f"未找到指定图像 ERR！{e}")
                            
                            elif flow.get("type") == "point":
                                point = flow.get("point", "")
                                if point and "," in point:
                                    points = point.split(",")
                                    # 移动鼠标到搜索框位置并点击
                                    pyautogui.moveTo(int(points[0]), int(points[1]), duration=0.5)
                                    pyautogui.click()
                                    self.log_signal.emit(f"找到坐标： {points[0]},{points[1]}")
                                    time.sleep(1)  
                                else:
                                    self.log_signal.emit(f"未找到坐标： {point}")
                            else:
                                resp = send_and_wait_response(json.dumps(flow), timeout=10)
                                if resp:
                                    self.log_signal.emit(f"浏览器返回：{resp}")
                                else:
                                    self.log_signal.emit("等待浏览器响应超时。")
                            
            elif type == "ht":
                self.running_task = True
                for task in self.tasks:
                    if not self.running_task:
                        self.log_signal.emit(f"外部原因，终止流程 当前执行到:{task.get('dsc')}")
                        break
                    # 检查是否是获取坐标点
                    if task.get("type") == "point":
                        jsonPath = task.get("jsonPath")
                        source = json.loads(self.source)
                        attachmentPaths = None
                        try:
                            attachmentPaths = glom(source, jsonPath)
                        except:
                            pass
                        if attachmentPaths and len(attachmentPaths) >0:
                            if self.extensions == "zip" and str(self.file_path).endswith("_extracted"):
                                files = get_all_files(self.file_path)
                                filters = [file for file in files if extract_filename_from_path(file) in attachmentPaths]
                                for file in filters:
                                    resp = send_and_wait_response(json.dumps(task), timeout=2)
                                    if resp:
                                        self.log_signal.emit(f"浏览器返回：{resp}")
                                        if resp and "," in resp:
                                            points = resp.split(",")
                                            pyautogui.moveTo(int(points[0]), int(points[1]), duration=0.5)
                                            pyautogui.click()
                                            self.log_signal.emit(f"找到坐标： {points[0]},{points[1]}")
                                            time.sleep(1)  
                                            self.log_signal.emit(f"准备上传附件 {file}")
                                            handle_file_dialog_by_handle(file)
                                            ack_field_text = send_and_wait_response(json.dumps(task.get("remark")), timeout=2)
                                            print(f"ack_field_text: {ack_field_text}")
                                            if extract_filename_from_path(file) in ack_field_text:
                                                print(f"附件上传成功{file}")
                                                self.log_signal.emit(f"附件上传成功 {file}")
                                            else:
                                                print(f"附件上传失败{file}")
                                                self.log_signal.emit(f"附件上传失败 {file}")
                                        else:
                                            self.log_signal.emit(f"未找到坐标： {resp}")
                                    else:
                                        self.log_signal.emit("等待浏览器响应超时。")
                            else:
                                self.log_signal.emit("扩展名不为 zip：{self.extensions} 或，解压文件失败 路径：{self.file_path}。")
                        else:
                            self.log_signal.emit(f" 在源数据中：{json.dumps(self.source)}没有获取到字段：{jsonPath}数据。")
                    else:
                        resp = send_and_wait_response(json.dumps(task), timeout=2)
                        if resp:
                            self.log_signal.emit(f"浏览器返回：{resp}")
                        else:
                            self.log_signal.emit("等待浏览器响应超时。")
            else:
                self.message_signal.emit("未知数据类型")
            self.running_task = False


    def open_webpage(self, url):
        import webbrowser
        
        if self.is_browser_open():
            self.maximize_all_chrome_windows()
            self.log_signal.emit(f"浏览器已启动")
            self.excute_task()
            # if has_clients():
            #     self.log_signal.emit(f"有客户端连接")
            #     print(f"有客户端连接")
            #     self.excute_task()
            # else:
            #     self.log_signal.emit(f"没有客户端连接")
            #     print(f"没有客户端连接")
            #     self.message_signal.emit("没有客户端连接,请检查浏览器插件是否正确运行。")
        else:
            self.log_signal.emit(f"浏览器未启动")
            print(f"浏览器未打开:{url}")
            
            try:
                webbrowser.open(url, new=2)
                if(self.wait_for_browser_open()):
                    pass
                time.sleep(2)
                self.maximize_all_chrome_windows()
                print(f"已打开网页:{url}")
                self.log_signal.emit(f"已打开网页:{url}")
                
                self.excute_task()
            except:
                self.log_signal.emit(f"网页打开失败:{url}")
                print("网页打开失败")

    def wait_for_browser_open(self, timeout=30):
        start_time = time.time()
        while not self.is_browser_open():
            if time.time() - start_time > timeout:
                print(f"❌ 等待浏览器打开超时（{timeout}s）")
                return False
            print("⏳ 等待浏览器启动中...")
            time.sleep(1)
        print("✅ 浏览器已打开！")
        return True
